#include <stdio.h>
#include <stdlib.h>
#include <execinfo.h>		//Backtrace
#include <signal.h>			//Backtrace
#include <ucontext.h>		//Backtrace

void  print_trace (void)
{
	void *array[10];
	size_t size;
	char **strings;
	size_t i;
     
	size = backtrace (array, 10);
	strings = backtrace_symbols (array, size);
     
	printf ("Obtained %zd stack frames.\n", size);
     
	for (i = 0; i < size; i++)
		printf ("%s\n", strings[i]);
     
	free (strings);
}

static void backtraceInHandler( int sig, siginfo_t* pSig, void *pUc )
{
	void		*trace[128];
	int			n = backtrace( trace, sizeof(trace) / sizeof(trace[0]) );
	ucontext_t	*pUctx = (ucontext_t *)pUc;
	void		*pEip = (void *)(pUctx->uc_mcontext.gregs[REG_PC]);	//[REG_EIP];
	
	printf( "sigsegv pc=0x%x\n", (unsigned int)pEip );
	printf( "n=%d\n", n );
	
	backtrace_symbols_fd( trace + 2, n - 2, 1 );	//-2: signal handling trace
}

void PrintBacktraceWhenSigsegv( void )
{
	struct sigaction	sa;
	
	memset( &sa, 0, sizeof(sa) );
	sa.sa_sigaction = crc_backtraceInHandler;
	sa.sa_flags = SA_ONESHOT | SA_SIGINFO;
	sigaction( SIGSEGV, &sa, NULL );
}
